package com.itlong.cloud.smartcard.service.impl;

import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.DTO.smartcard.SmartCardFaceSyncDataGetPageDTO;
import com.itlong.cloud.POJO.PO.DeviceElevatorBridgeInfoPO;
import com.itlong.cloud.POJO.PO.DeviceEntranceBridgeInfoPO;
import com.itlong.cloud.POJO.PO.SmartCardFacePullCloudInfoPO;
import com.itlong.cloud.POJO.VO.app.AppDoorDevicesVO;
import com.itlong.cloud.POJO.VO.app.AppFloorDevicesVO;
import com.itlong.cloud.POJO.VO.smartcard.SmartCardFaceSyncDataPageVO;
import com.itlong.cloud.POJO.VO.smartcard.SmartCardFaceUserInfoVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.app.service.IAppDeviceService;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.PadUserStatusEnum;
import com.itlong.cloud.property.dao.IPadFaceSyncDataServiceDao;
import com.itlong.cloud.smartcard.dao.ISmartCardFaceDao;
import com.itlong.cloud.smartcard.service.ISmartCardFaceService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
* <desc>
*     C#人脸识别全量同步数据处理类.
* </desc>
*
* @createDate 2019-03-18
*/
@Service
public class SmartCardFaceServiceImpl implements ISmartCardFaceService {


    private static Logger LOG = LoggerFactory.getLogger(SmartCardFaceServiceImpl.class);

    @Autowired
    private ISmartCardFaceDao iSmartCardFaceDao;

    @Autowired
    private IPadFaceSyncDataServiceDao iPadFaceSyncDataServiceDao;

    @Autowired
    IAppDeviceService iAppDeviceService;

    /**
     * <desc>
     *      C#人脸识别获取全量数据
     * </desc>
     *
     * @param syncDataGetPageDTO    数据传输对象
     * @return
     * @author Juguang.S
     * @createDate 2019/03/18
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Page<SmartCardFaceSyncDataPageVO> pullFull(SmartCardFaceSyncDataGetPageDTO syncDataGetPageDTO) throws Exception {
        boolean blank = StringUtils.isBlank(syncDataGetPageDTO.getDeviceUnique());
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(syncDataGetPageDTO);
        Page<SmartCardFaceSyncDataPageVO> page = new Page<>();
        page.getPage().setPageSize(syncDataGetPageDTO.getPageSize());
        page.getPage().setCurrentPage(syncDataGetPageDTO.getCurrentPage());
        params.put("projectId", syncDataGetPageDTO.getProjectId());
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());

        String deviceUnique = syncDataGetPageDTO.getDeviceUnique();
        String projectId = syncDataGetPageDTO.getProjectId();
        Map<String,Object> data = new HashMap<>();
        SmartCardFaceSyncDataPageVO dataPageVO = new SmartCardFaceSyncDataPageVO();
        List<SmartCardFaceSyncDataPageVO> pageList = new ArrayList<>();
        Integer count = 0;
        //deviceUnique为空则查询整个项目下的全量信息
        if(StringUtils.isEmpty(deviceUnique)){
            //首先将增量表中的该项目下的未被消费的指令改为已消费
            if(syncDataGetPageDTO.getCurrentPage().equals("1")){
                iSmartCardFaceDao.updateCommandStatus(projectId);
            }
            List<String> buildList = iSmartCardFaceDao.getBuildInfoByProjectId(projectId);
            if(null == buildList || buildList.isEmpty()){
               return page;
            }
            //获取项目下的所有的用户信息 由于此处需兼容没有房间的分组人员数据故不根据楼栋ID
            params.put("buildIds", null);
            List<SmartCardFaceUserInfoVO> vos = iSmartCardFaceDao.getUserInfosByBuilds(params);
            count = iSmartCardFaceDao.getUserInfosByBuildsCount(params);
            //校验如是最后一页，则将访客信息一并返回
            Integer totalPage = (int)(Math.ceil((float)count / (float)Integer.valueOf(syncDataGetPageDTO.getPageSize())));
            if(syncDataGetPageDTO.getCurrentPage().equals(totalPage+"")){
                List<SmartCardFaceUserInfoVO> visitors = iSmartCardFaceDao.getVisitorFaceInfosByBuilds(buildList,
                        DateUtil.fomatDate(new Date(),DateUtil.DATE_FORMAT_TYPE1));
                vos.forEach(vo->{
                    if(vo.getStatus() == PadUserStatusEnum.NORMAL.getType() && vo.getOutstandingAccounts() ==0){
                        vo.setStatus(vo.getOutstandingAccounts());
                    }
                });
                vos.addAll(visitors);
            }
            data.put("userInfo",vos);
        }else{
            //deviceUnique不为空则查询该设备下的全量信息
            List<Map<String,Object>> builds = iSmartCardFaceDao.getAddressByDeviceUnique(deviceUnique);

            if(builds.size() > 1 ){
                //多楼栋
                List<String> bs = new ArrayList<>();
                builds.forEach(build->{
                    bs.add(build.get("buildId").toString());
                });
                params.put("buildIds", bs);
                List<SmartCardFaceUserInfoVO> vos = iSmartCardFaceDao.getUserInfosByBuilds(params);
                count = iSmartCardFaceDao.getUserInfosByBuildsCount(params);
                //校验如是最后一页，则将访客信息一并返回
                Integer totalPage = (int)(Math.ceil((float)count / (float)Integer.valueOf(syncDataGetPageDTO.getPageSize())));
                if(syncDataGetPageDTO.getCurrentPage().equals(totalPage+"")){
                    List<SmartCardFaceUserInfoVO> visitors = iSmartCardFaceDao.getVisitorFaceInfosByBuilds(bs,
                            DateUtil.fomatDate(new Date(),DateUtil.DATE_FORMAT_TYPE1));
                    vos.forEach(vo->{
                        if(vo.getStatus() == PadUserStatusEnum.NORMAL.getType() && vo.getOutstandingAccounts() ==0){
                            vo.setStatus(vo.getOutstandingAccounts());
                        }
                    });
                    vos.addAll(visitors);
                }
                data.put("userInfo",vos);
            }else if(builds.size() == 1){
                //多单元
                String[] unit = StringHandlerUtil.splitString(builds.get(0).get("unitId").toString());
                params.put("unitIds", unit);
                List<SmartCardFaceUserInfoVO> vos = iSmartCardFaceDao.getUserInfosByUnits(params);
                count = iSmartCardFaceDao.getUserInfosByUnitsCount(params);
                //校验如是最后一页，则将访客信息一并返回
                Integer totalPage = (int)(Math.ceil((float)count / (float)Integer.valueOf(syncDataGetPageDTO.getPageSize())));
                if(syncDataGetPageDTO.getCurrentPage().equals(totalPage+"")){
                    List<SmartCardFaceUserInfoVO> visitors = iSmartCardFaceDao.getVisitorFaceInfosByUnits(unit,
                            DateUtil.fomatDate(new Date(), DateUtil.DATE_FORMAT_TYPE1));
                    vos.forEach(vo->{
                        if(vo.getStatus() == PadUserStatusEnum.NORMAL.getType() && vo.getOutstandingAccounts() ==0){
                            vo.setStatus(vo.getOutstandingAccounts());
                        }
                    });
                    vos.addAll(visitors);
                }
                data.put("userInfo",vos);
            }
        }
        //组装用户权限信息
        List<String> userIdList = new ArrayList<>();
        List<SmartCardFaceUserInfoVO> users = (List<SmartCardFaceUserInfoVO>) data.get("userInfo");
        List<Map<String, Object>> auths = new ArrayList<>();
        if(users !=null){
            for (SmartCardFaceUserInfoVO user : users) {
                List<Map<String, Object>> sysAuths = new ArrayList<>();
                Map<String, Object> auth = new HashMap<>();
                String userId = user.getUserId();
                userIdList.add(user.getUserId());
                //如果userId不以V_为前缀则代表为住户 否则为访客
                if(userId.startsWith("V_") || user.getHouserType()==4){
                    userId = iSmartCardFaceDao.getUserIdByVFaceId(userId,user.getId());
                }

                //门禁
                List<AppDoorDevicesVO> doors = iAppDeviceService.getDoorDevices(userId, syncDataGetPageDTO.getProjectId(), 0);
                auth.put("userId", user.getUserId());
                auth.put("id",user.getId());
                for (AppDoorDevicesVO door : doors) {
                    if(user.getHouserType()==4){
                        // 业主可能存在多个楼栋或单元，找到访客地址对应的门禁再生成数据
                        DeviceEntranceBridgeInfoPO deviceEntranceBridgeInfoPO = iPadFaceSyncDataServiceDao.getEntranceBridge(door.getDeviceUnique());
                        if (deviceEntranceBridgeInfoPO == null) {
                            continue;
                        }
                        if (StringUtils.isNotBlank(deviceEntranceBridgeInfoPO.getUnitId()) && !deviceEntranceBridgeInfoPO.getUnitId().contains(user.getUnitId())) {
                            continue;
                        }
                        if (StringUtils.isNotBlank(deviceEntranceBridgeInfoPO.getBuildId()) && !deviceEntranceBridgeInfoPO.getBuildId().contains(user.getBuildId())) {
                            continue;
                        }
                    }
                    Map<String, Object> sysAuth = new HashMap<>();
                    sysAuth.put("deviceType", 2);
                    sysAuth.put("auth", "8");
                    sysAuth.put("deviceUnique", door.getDeviceUnique());
                    if((StringUtils.isNotBlank(door.getDoorType()) && door.getDoorType().contains("3")) ||
                            (StringUtils.isNotBlank(door.getDoorType()) && door.getDoorType().contains("1,3"))){
                        sysAuth.put("isWippen","1");
                    }else{
                        sysAuth.put("isWippen","0");
                    }
                    sysAuths.add(sysAuth);
                }
                //电梯
                List<AppFloorDevicesVO> floorsList = iAppDeviceService.getFloorDevicesByNoStardard(userId, syncDataGetPageDTO.getProjectId(), 0);
                for (AppFloorDevicesVO floorInfo : floorsList) {
                    if(iSmartCardFaceDao.isCloudElevator(floorInfo.getDeviceUnique())>0){
                        Map<String, Object> sysAuth = new HashMap<>();
                        if(user.getHouserType()==4){
                            // 业主可能存在多个楼栋或单元，找到访客地址对应的电梯再生成数据
                            DeviceElevatorBridgeInfoPO deviceElevatorBridgeInfoPO = iPadFaceSyncDataServiceDao.getElevatorBridge(floorInfo.getDeviceUnique());
                            if (deviceElevatorBridgeInfoPO == null) {
                                continue;
                            }
                            if (!(deviceElevatorBridgeInfoPO.getBuildId().contains(user.getBuildId()) &&
                                    deviceElevatorBridgeInfoPO.getUnitId().contains(user.getUnitId()))) {
                                continue;
                            }
                            // 业主可能存在多个房间，给到对应房间的楼层
                            sysAuth.put("auth",iPadFaceSyncDataServiceDao.getNaturalFloorByFloorNum(user.getFloorNum(), floorInfo.getDeviceUnique()));
                            if(user.getLiftDoorType().equals("1")){
                                sysAuth.put("mainFloor",iPadFaceSyncDataServiceDao.getNaturalFloorByFloorNum(user.getFloorNum(), floorInfo.getDeviceUnique()));
                            }else{
                                sysAuth.put("backFloor",iPadFaceSyncDataServiceDao.getNaturalFloorByFloorNum(user.getFloorNum(), floorInfo.getDeviceUnique()));
                            }
                        }else{
                            sysAuth.put("auth", floorInfo.getLiveFloor());
                            sysAuth.put("mainFloor",floorInfo.getMainFloor());
                            sysAuth.put("backFloor",floorInfo.getBackFloor());
                        }
                        //处理用户在电梯设备中所设置的常用楼层
                        if(StringUtils.isNotBlank(user.getUserAllCommonFloor())){
                            Map<String,Object> commanFloors = JsonUtil.toObject(user.getUserAllCommonFloor(),HashMap.class);
                            if(commanFloors.containsKey(floorInfo.getDeviceUnique())){
                                if(StringUtils.isNotEmpty(floorInfo.getLiveFloor()) && Arrays.asList(floorInfo.getLiveFloor().split(",")).contains(commanFloors.get(floorInfo.getDeviceUnique()).toString())){
                                    sysAuth.put("commonFloor", commanFloors.get(floorInfo.getDeviceUnique()).toString());
                                }else{
                                    sysAuth.put("commonFloor", "");
                                }
                            }else{
                                sysAuth.put("commonFloor", "");
                            }
                        }else{
                            sysAuth.put("commonFloor", "");
                        }

                        sysAuth.put("deviceType", 1);
                        sysAuth.put("deviceUnique", floorInfo.getDeviceUnique());
                        sysAuths.add(sysAuth);
                    }
                }
                auth.put("sysAuths", sysAuths);
                auths.add(auth);
            }
        }
        data.put("authInfo", auths);


        List<Map<String,Object>> floors = new ArrayList<>();
        List<String> deviceUniqueAuth = null;
        Set<String> deviceUniqueList = new HashSet<>();
        //获取该项目下所有的电梯设备
        if(StringUtils.isNotEmpty(deviceUnique) && deviceUnique.substring(8,9).equals("1")){
            deviceUniqueList.add(deviceUnique);
        }else if(StringUtils.isNotEmpty(deviceUnique) && deviceUnique.substring(8,9).equals("2")){
            data.put("authInfo", auths);
            dataPageVO.setMap(data);
            pageList.add(dataPageVO);
            page.setRows(pageList,count);

            return page;
        } else{
            //根据当前所查的userId集合和projectId查询当前相关的设备唯一码
            if(userIdList.size()>0 ){
                deviceUniqueAuth = iSmartCardFaceDao.getElevatorInfoByProjectId(userIdList,projectId);
            }else{
                deviceUniqueAuth = new ArrayList<>();
            }
            for(String deviceAuthStr : deviceUniqueAuth){
                if (StringUtils.isNotBlank(deviceAuthStr)) {
                    int i = deviceAuthStr.indexOf("1");
                    while (i != -1) {
                        int deviceInt = i + 1;
                        String deviceId = StringHandlerUtil.formatStrLen(deviceInt + "", "0", 4, false, false);
                        //判断该电梯是否为云电梯
                        String elevatorDeviceUnique = projectId + "1" + deviceId;
                        if(iSmartCardFaceDao.isCloudElevator(elevatorDeviceUnique)>0){
                            deviceUniqueList.add(elevatorDeviceUnique);
                        }
                        i = deviceAuthStr.indexOf("1", deviceInt);
                    }
                }
            }
        }
        //组装楼层对应表信息
        //for(String str : deviceUniqueList){
        //    //获取电梯起始楼层及结束楼层
        //    Map<String,Object> minAndMaxFloor = iPadFaceSyncDataServiceDao.getMinAndMaxFloor(str);
        //    Integer startFloor = minAndMaxFloor==null || minAndMaxFloor.get("minFloor") == null ? null : Double.valueOf(minAndMaxFloor.get("minFloor").toString()).intValue();
        //    Integer endFloor = minAndMaxFloor==null || minAndMaxFloor.get("maxFloor") == null ? null : Double.valueOf(minAndMaxFloor.get("maxFloor").toString()).intValue();
        //    Map<String,Object> floor =iPadFaceSyncDataServiceDao.getFloorsByDeviceUnique(str,startFloor,endFloor);
        //    if(floor!=null){
        //        floors.add(floor);
        //    }
        //}
        //data.put("floorMappingInfo", floors);
        if(syncDataGetPageDTO.getCurrentPage().equals("1")){
            //当请求当前页为第一页时则组装该项目下云群控器与所绑定云电梯间的关系
            List<Map<String, Object>> syncDataListMap = iPadFaceSyncDataServiceDao.getControllerElevatorByProjectId(projectId);
            data.put("cloudControllerElevatorInfo",syncDataListMap);
        }else{
            data.put("cloudControllerElevatorInfo","");
        }
        dataPageVO.setMap(data);
        pageList.add(dataPageVO);
        page.setRows(pageList,count);

        // 当以项目获取全量数据时，返回全量数据之前删除所有增量数据
        if (blank) {
            iSmartCardFaceDao.deletePullDataByProjectId(syncDataGetPageDTO.getProjectId());
        }
        return page;
    }

    /**
     * <desc>
     *      推送用户权限信息变更消息
     * </desc>
     *
     * @param json
     * @author Juguang.S
     * @createDate 2019/03/20
     */
    @Override
    public void pushUserAuthChange(String json,String projectId) throws Exception {
        SmartCardFacePullCloudInfoPO pullCloudInfoPO = new SmartCardFacePullCloudInfoPO();
        pullCloudInfoPO.setProjectId(projectId);
        pullCloudInfoPO.setSyncData(json);
        pullCloudInfoPO.setSyncType(2);
        pullCloudInfoPO.setSyncSerialNo(LogicIdUtil.bussinessId());
        pullCloudInfoPO.setDataType(2);
        pullCloudInfoPO.setSyncStatus(1);
        pullCloudInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
        pullCloudInfoPO.setCreateTime(new Date());
        iSmartCardFaceDao.save(SqlUtil.durableData(pullCloudInfoPO, PlatformConstants.TABLE_SAVE));
    }

    /**
     * <desc>
     *      根据访客人脸url获取邀请该访客创建人脸的用户ID
     * </desc>
     *
     * @param userId
     * @author Juguang.S
     * @createDate 2019/03/20
     */
    @Override
    public String getUserIdByVFaceId(String userId) {
        return iSmartCardFaceDao.getUserIdByVFaceId(userId,"");
    }

    /**
     * <desc>
     *      判断该电梯是否为云电梯
     * <desc/>
     * @param   elevatorDeviceUnique 电梯设备唯一码
     * @return
     * @author Juguang.S
     * @createDate 2019/03/20
     */
    @Override
    public Integer isCloudElevator(String elevatorDeviceUnique) {
        return iSmartCardFaceDao.isCloudElevator(elevatorDeviceUnique);
    }

    /**
     * <desc>
     *      保存一卡通动态人脸识别同步后台数据
     * <desc/>
     * @param   deviceUniqueStr 设备唯一码，多个以逗号隔开
     * @param   status 设备启用状态 1-启用 2-禁用
     * @return
     * @author Juguang.S
     * @createDate 2019/07/02
     */
    @Override
    public List<Map<String, Object>> saveVisitorInfo(String deviceUniqueStr, String status,List<Map<String, Object>> auths,String projectId) {
        List<SmartCardFacePullCloudInfoPO> smartCardFacePullCloudInfoPOList = new ArrayList<>();
        Set<String> set = new HashSet<>();
        List<Map<String,Object>> list = iSmartCardFaceDao.getDeviceAdress(deviceUniqueStr.split(","));
        for(Map<String,Object> map : list){
            if(map.size()==2){
                set.add(map.get("unitId").toString());
            }else{
                List<String> unitList = iSmartCardFaceDao.getUnitidInfo(map.get("buildId").toString());
                set.addAll(unitList);
            }
        }
        String[] unitIds=set.toArray(new String[set.size()]);
        if(unitIds==null || unitIds.length==0){
            return auths;
        }
        List<SmartCardFaceUserInfoVO> userList = iSmartCardFaceDao.getVisitorFaceInfosByUnits(unitIds,DateUtil.fomatDate(new Date(), DateUtil.DATE_FORMAT_TYPE1));
        //如果设备禁用则只需要向人脸识别系统推送用户信息
        if(status.equals("2") && userList!=null && userList.size()>0){
            for(SmartCardFaceUserInfoVO infoVO : userList){
                infoVO.setStatus(2);
            }
        }
        if(status.equals("1") && userList!=null && userList.size()>0){
            //设备启用
            for(SmartCardFaceUserInfoVO infoVO : userList){
                List<Map<String, Object>> sysAuths = new ArrayList<>();
                Map<String, Object> auth = new HashMap<>();
                auth.put("userId", infoVO.getUserId());
                auth.put("id",infoVO.getUserId());

                //门禁
                List<Map<String,Object>> doors = iSmartCardFaceDao.getEntranceByUnitid(infoVO.getBuildId(),infoVO.getUnitId());
                for (Map<String,Object> door : doors) {
                    Map<String, Object> sysAuth = new HashMap<>();
                    sysAuth.put("deviceType", 2);
                    sysAuth.put("auth", "8");
                    sysAuth.put("deviceUnique", door.get("deviceUnique").toString());
                    if(door.get("entranceCategory").toString().equals("23")){
                        sysAuth.put("isWippen","1");
                    }else{
                        sysAuth.put("isWippen","0");
                    }
                    sysAuths.add(sysAuth);
                }
                //电梯
                List<String> floorsList = iSmartCardFaceDao.getElevatorByUnitid(infoVO.getUnitId());
                for (String deviceUnique : floorsList) {
                    Map<String, Object> sysAuth = new HashMap<>();
                    sysAuth.put("deviceType", 1);
                    sysAuth.put("auth",iPadFaceSyncDataServiceDao.getNaturalFloorByFloorNum(infoVO.getFloorNum(), deviceUnique));
                    sysAuth.put("deviceUnique", deviceUnique);
                    sysAuths.add(sysAuth);

                }
                auth.put("sysAuths", sysAuths);
                auths.add(auth);
            }
        }
        if(userList!=null  && userList.size()>0){
            // 组装插入表的数据
            SmartCardFacePullCloudInfoPO smartCardFacePullCloudInfoPO = new SmartCardFacePullCloudInfoPO();
            smartCardFacePullCloudInfoPO.setProjectId(projectId);
            String syncData = JSON.toJSONString(userList);
            smartCardFacePullCloudInfoPO.setSyncData(syncData);
            smartCardFacePullCloudInfoPO.setSyncType(2);
            smartCardFacePullCloudInfoPO.setSyncSerialNo(LogicIdUtil.bussinessId());
            smartCardFacePullCloudInfoPO.setDataType(1);
            smartCardFacePullCloudInfoPO.setSyncStatus(1);
            smartCardFacePullCloudInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
            smartCardFacePullCloudInfoPO.setCreateTime(new Date());
            smartCardFacePullCloudInfoPO.setUpdateTime(new Date());
            smartCardFacePullCloudInfoPOList.add(smartCardFacePullCloudInfoPO);
        }
        if(!smartCardFacePullCloudInfoPOList.isEmpty()  && smartCardFacePullCloudInfoPOList.size()>0){
            iPadFaceSyncDataServiceDao.batchSaveSmartCard(smartCardFacePullCloudInfoPOList);
        }
        return auths;
    }

    /**
     * <desc>
     *      获取项目有批号设备的过期时间集合。
     * <desc/>
     *
     * @param projectId 项目编号
     * @return
     * @author Juguang.S
     * @createDate 2019-11-25
     */
    @Override
    public List<Map<String, String>> getDeviceCloudServiceCostEndTime(String projectId) {
        return iSmartCardFaceDao.getDeviceCloudServiceCostEndTime(projectId);
    }
}
